﻿using D.Medicalcare.Domain.Entities;
using D.Medicalcare.ErrorCode;
using D.Medicalcare.Infrastructure.Interfaces;
using D.Medicalcare.Read.API.Application.Command.DoctorSchedulingCommand;
using D.Medicalcare.Read.API.Dtos;
using DocumentFormat.OpenXml.Wordprocessing;
using MediatR;
using static D.Medicalcare.Read.API.Application.Handler.DoctorSchedulingHandler.GetDoctorSchedulingHandler;

namespace D.Medicalcare.Read.API.Application.Handler.DoctorSchedulingHandler
{
    /// <summary>
    /// 获取排班信息
    /// </summary>
    public class GetDoctorSchedulingHandler : IRequestHandler<GetDoctorSchedulingCommand, DoctorSchedulingResult>
    {
        private readonly IBaseRepository<DoctorScheduling> baseRepository;
        private readonly IBaseRepository<Department> deparableRepository;
        private readonly IBaseRepository<Doctor> doctorRepository;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="baseRepository"></param>
        /// <param name="deparableRepository"></param>
        /// <param name="doctorRepository"></param>

        public GetDoctorSchedulingHandler(IBaseRepository<DoctorScheduling> baseRepository, IBaseRepository<Department> deparableRepository, IBaseRepository<Doctor> doctorRepository)
        {
            this.baseRepository = baseRepository;
            this.deparableRepository = deparableRepository;
            this.doctorRepository = doctorRepository;
        }
        /// <summary>
        /// 处理
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<DoctorSchedulingResult> Handle(GetDoctorSchedulingCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 获取当前日期
                DateTime today = DateTime.Today;

                // 计算本周第一天（星期一）
                DateTime firstDayOfWeek = today.AddDays(-(int)today.DayOfWeek + (int)DayOfWeek.Monday);
                // 如果今天是周日，需要特殊处理
                if (today.DayOfWeek == DayOfWeek.Sunday)
                {
                    firstDayOfWeek = today.AddDays(-6);
                }

                // 生成本周七天日期
                List<DateTime> weekDates = Enumerable.Range(0, 7)
                    .Select(offset => firstDayOfWeek.AddDays(offset))
                    .ToList();

                var list = (from a in baseRepository.GetAll()
                            join b in doctorRepository.GetAll() on a.DoctorId equals b.DoctorId
                            join c in deparableRepository.GetAll() on b.DeparId equals c.DeparId
                            select new DoctorSchedulingDto()
                            {
                                DoctorId = a.DoctorId,
                                DoctorName = b.DoctorName,
                                DeparId = b.DeparId,
                                DeparName = c.DeparName,
                                MorningNumberSources = a.MorningNumberSources,
                                AfternoonNumberSources = a.AfternoonNumberSources,
                                MorningNumberPatients = a.MorningNumberPatients,
                                AfternoonAdmissions = a.AfternoonAdmissions,
                                AfternoonNumberPatients = a.AfternoonNumberPatients,
                                Date = a.Date,
                                MorningAdmissions = a.MorningAdmissions,
                                MorningIsNo = a.MorningIsNo,
                                AfternoonIsNo = a.AfternoonIsNo,
                                IsScheduling = a.IsScheduling
                            }).ToList();

                // 1          2  3 4  
                // 1 1 1 1 

                List<string> dateList = new List<string>();
                foreach (var item in weekDates)
                {
                    dateList.Add($"{item.ToString("yyyy-MM-dd")} {GetChineseDayOfWeek(item.DayOfWeek)}");
                }
                var resultList = new List<DoctorSchedulingResultDto>();

                foreach (var item in list.GroupBy(x => new { x.DoctorId, x.DoctorName, x.DeparName, x.DeparId, x.Date }))
                {
                    var mode = new DoctorSchedulingResultDto()
                    {
                        DoctorId = item.Key.DoctorId,
                        DoctorName = item.Key.DoctorName,
                        DeparId = item.Key.DeparId,
                        DeparName = item.Key.DeparName,
                    };
                    var temp = list.FirstOrDefault(x => x.DoctorId == item.Key.DoctorId && x.Date == item.Key.Date);

                    AssignValueByDate(mode, item.Key.Date, temp);
                    resultList.Add(mode);
                }

                return await Task.FromResult(new DoctorSchedulingResult()
                {
                    Date = dateList,
                    List = resultList
                });

            }
            catch (Exception)
            {

                throw;
            }
        }

        // 将DayOfWeek转换为中文星期几
        private string GetChineseDayOfWeek(DayOfWeek dayOfWeek)
        {
            return dayOfWeek switch
            {
                DayOfWeek.Sunday => "星期日",
                DayOfWeek.Monday => "星期一",
                DayOfWeek.Tuesday => "星期二",
                DayOfWeek.Wednesday => "星期三",
                DayOfWeek.Thursday => "星期四",
                DayOfWeek.Friday => "星期五",
                DayOfWeek.Saturday => "星期六",
                _ => string.Empty
            };
        }

        /// <summary>
        /// 根据日期设置排班
        /// </summary>
        /// <param name="data"></param>
        /// <param name="date"></param>
        /// <param name="value"></param>
        public void AssignValueByDate(DoctorSchedulingResultDto data, DateTime date, DoctorSchedulingDto value)
        {
           
            switch (date.DayOfWeek)
            {
                case DayOfWeek.Monday:
                    //当天是否排班
                    data.MorningNumberSources0 = !value.IsScheduling.Value || !value.MorningIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources0 = !value.IsScheduling.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    //上午是否有号 
                    data.AfternoonNumberSources0 = !value.MorningIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    //下午是否有号
                    data.AfternoonNumberSources0 = !value.AfternoonIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    break;

                case DayOfWeek.Tuesday:
                    data.MorningNumberSources1 = !value.IsScheduling.Value || !value.MorningIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources1 = !value.IsScheduling.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    data.AfternoonNumberSources1 = !value.MorningIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources1 = !value.AfternoonIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    break;

                case DayOfWeek.Wednesday:
                    data.MorningNumberSources2 = !value.IsScheduling.Value || !value.MorningIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources2 = !value.IsScheduling.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    data.AfternoonNumberSources2 = !value.MorningIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources2 = !value.AfternoonIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    break;
                case DayOfWeek.Thursday:
                    data.MorningNumberSources3 = !value.IsScheduling.Value || !value.MorningIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources3 = !value.IsScheduling.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    data.AfternoonNumberSources3 = !value.MorningIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources3 = !value.AfternoonIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    break;
                case DayOfWeek.Friday:
                    data.MorningNumberSources4 = !value.IsScheduling.Value || !value.MorningIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources4 = !value.IsScheduling.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    data.AfternoonNumberSources4 = !value.MorningIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources4 = !value.AfternoonIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    break;
                case DayOfWeek.Saturday:
                    data.MorningNumberSources5 = !value.IsScheduling.Value || !value.MorningIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources5 = !value.IsScheduling.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    data.AfternoonNumberSources5 = !value.MorningIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources5 = !value.AfternoonIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    break;
                case DayOfWeek.Sunday:
                    data.MorningNumberSources6 = !value.IsScheduling.Value || !value.MorningIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources6 = !value.IsScheduling.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    data.AfternoonNumberSources6 = !value.MorningIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.MorningNumberSources.ToString();
                    data.AfternoonNumberSources6 = !value.AfternoonIsNo.Value || !value.AfternoonIsNo.Value ? "休息" : value.AfternoonNumberSources.ToString();
                    break;
            }
        }
        /// <summary>
        /// 医生排班结果集合
        /// </summary>
        public class DoctorSchedulingResult
        {
            public List<string> Date { get; set; }
            public List<DoctorSchedulingResultDto> List { get; set; }
        }
        /// <summary>
        /// 医生排班结果
        /// </summary>
        public class DoctorSchedulingResultDto
        {
            /// <summary>
            /// 医生ID
            /// </summary>
            public int? DoctorId { get; set; }
            /// <summary>
            /// 医生名称
            /// </summary>
            public string? DoctorName { get; set; }
            /// <summary>
            /// 科室ID
            /// </summary>
            public int? DeparId { get; set; }
            /// <summary>
            /// 科室名称
            /// </summary>
            public string? DeparName { get; set; }
            /// <summary>
            /// 上午号源数
            /// </summary>
            public string MorningNumberSources0 { get; set; } = "休息";
            /// <summary>
            /// 下午号源数
            /// </summary>
            public string AfternoonNumberSources0 { get; set; } = "休息";

            /// <summary>
            /// 上午号源数
            /// </summary>
            public string MorningNumberSources1 { get; set; } = "休息";
            /// <summary>
            /// 下午号源数
            /// </summary>
            public string AfternoonNumberSources1 { get; set; } = "休息";

            /// <summary>
            /// 上午号源数
            /// </summary>
            public string MorningNumberSources2 { get; set; } = "休息";
            /// <summary>
            /// 下午号源数
            /// </summary>
            public string AfternoonNumberSources2 { get; set; } = "休息";

            /// <summary>
            /// 上午号源数
            /// </summary>
            public string MorningNumberSources3 { get; set; } = "休息";
            /// <summary>
            /// 下午号源数
            /// </summary>
            public string AfternoonNumberSources3 { get; set; } = "休息";

            /// <summary>
            /// 上午号源数
            /// </summary>
            public string MorningNumberSources4 { get; set; } = "休息";
            /// <summary>
            /// 下午号源数
            /// </summary>
            public string AfternoonNumberSources4 { get; set; } = "休息";

            /// <summary>
            /// 上午号源数
            /// </summary>
            public string MorningNumberSources5 { get; set; } = "休息";
            /// <summary>
            /// 下午号源数
            /// </summary>
            public string AfternoonNumberSources5 { get; set; } = "休息";

            /// <summary>
            /// 上午号源数
            /// </summary>
            public string MorningNumberSources6 { get; set; } = "休息";
            /// <summary>
            /// 下午号源数
            /// </summary>
            public string AfternoonNumberSources6 { get; set; } = "休息";

        }
    }
}
